<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit|ie-comp|ie-stand">
    <meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <title>模拟室内漫游</title>
<!--    <link rel="stylesheet" href="../public/plugins/ys/ys.min.css">-->
</head>
<body>
<div class="ys-absolute-container" id="box" style="overflow: hidden;cursor: hand"></div>
<div class="fix-btns">
    <span class="ys-btn ys-btn-warm ys-btn-sm  tips-btn">小记</span>
</div>
<div class="tips-container ys-absolute-container">
    <div class="ys-tit">模拟室内漫游</div>
    <div class="ys-block">

    </div>
</div>
</body>
<script src="../public/plugins/others/jquery-1.10.2.min.js"></script>
<script src="../public/plugins/ys/ys.min.js"></script>
<script src="../public/plugins/threeLibrary/js/loaders/ColladaLoader.js"></script>
<script src="../public/plugins/threeLibrary/js/lines/MeshLine.js"></script>
<script src="../public/plugins/others/mui.min.js"></script>
<script src="../public/plugins/ysThree/ysThree_1.0.0.js"></script>
<script type="module">
  import * as THREE from '../../../../three.js-source-code/build/three.module.js'
  import {TWEEN} from '../../../../three.js-source-code/examples/jsm/libs/tween.module.min.js'
  import {OrbitControls} from '../../../../three.js-source-code/examples/jsm/controls/OrbitControls.js'
  import Stats from '../../../../three.js-source-code/examples/js/libs/stats.min.js'
  const el = document.getElementById('box')
  ysThree.init({
    el:el,
    cameraType:1,
    // gridHelper:true,//网格参考线
    // axes:true,//坐标辅助
    clearColor:'#000'//画布颜色
  },(scene,camera,renderer)=>{
    renderer.setPixelRatio( window.devicePixelRatio )
    renderer.shadowMap.enabled = true



    //add light
    const directionalLight = new THREE.DirectionalLight( '#fff' )
    directionalLight.position.set( 30, 30, 30 ).normalize()
    scene.add( directionalLight )
    directionalLight.castShadow = true
    const ambientLight = new THREE.AmbientLight('#fff',0.3) // obj 唯一 id
    scene.add(ambientLight)
    const pointLight = new THREE.PointLight( 'yellow',2 )
    pointLight.position.set( 0, 30, 0 )
    pointLight.castShadow = true
    scene.add( pointLight )

    /*  ***********/

    /** add home */
    const home = new THREE.Mesh(new THREE.BoxBufferGeometry(1000,100,1000),[
      new THREE.MeshStandardMaterial({color :'red',side:THREE.BackSide}),
      new THREE.MeshStandardMaterial({color :'red',side:THREE.BackSide}),
      new THREE.MeshStandardMaterial({color :'red',side:THREE.BackSide}),
      new THREE.MeshStandardMaterial({color :'red',side:THREE.BackSide}),
      new THREE.MeshStandardMaterial({color :'red',side:THREE.BackSide}),
      new THREE.MeshStandardMaterial({color :'red',side:THREE.BackSide})
    ])
    home.position.set(0,50,0)
    scene.add(home)

    /** add plane */
    const plane = new THREE.Mesh(new THREE.PlaneGeometry(1000,1000),new THREE.MeshStandardMaterial({color:'#fff',sde:THREE.DoubleSide}))
    plane.rotateX(-Math.PI/2)
    plane.name = 'plane'
    plane.position.set(0,0.1,0)
    scene.add(plane)
    plane.receiveShadow = true


    function addBox () {
      return   new THREE.Mesh(new THREE.BoxBufferGeometry(4,10,4),new THREE.MeshStandardMaterial({color:ysThree.randomColor()}))
    }
    /** add box1 */
      //外边框线
    const  lineMaterial = new THREE.LineBasicMaterial({
        // 线的颜色
        color: "#fff",
        transparent: true,
        opacity: 0.8,
        depthFunc: THREE.AlwaysDepth
      })
    for(let i =0 ;i<50 ;i++) {
      const box1 = addBox()
      box1.position.set(Math.random()*1000-500,5,Math.random()*1000-500)
      scene.add(box1)
      box1.castShadow = true
      const borderLine = new THREE.LineSegments(new THREE.EdgesGeometry(box1.geometry), lineMaterial)
      box1.name = 'box'
      borderLine.name  = 'border'
      borderLine.visible = false
      box1.add(borderLine)
    }

    /** add circle for mousemove on the plane */
    const circle = new THREE.Mesh( new THREE.CircleGeometry(5,50),new THREE.MeshBasicMaterial({
      color:'green',
      transparent:true,
      opacity:0.2,
      side:THREE.DoubleSide
    }))
    circle.visible = false
    circle.rotateX(-0.5*Math.PI)
    circle.name = 'circle'
    scene.add(circle)
    let circleBorder
    const loader  = new THREE.TextureLoader()
    loader.load("../public/images/ysThree/redCircle2.png",texture =>{
      circle.material = new THREE.MeshBasicMaterial({
        map:texture,
        transparent:true,
        opacity:0.9,
        side:THREE.DoubleSide,
        depthTest:false
      })
      circleBorder = new THREE.Mesh( new THREE.CircleGeometry(5,50), circle.material)
      circleBorder.position.y = 0.2
      circle.add(circleBorder)
    })


    let timeout;//用于存储定时器的变量
    let isMoving = false
    $(el).mousedown(function() {
      timeout= setTimeout(function() {
        isMoving = true
        circle.visible = false
        $("body").css({
          cursor:'grab'
        })
      }, 200);//鼠标按下0.5秒后发生alert事件
    }).mouseup(function() {
      isMoving = false
      clearTimeout(timeout);//清理掉定时器
    })
    let currentHover
    el.addEventListener('mousemove',function (event) {
      event.preventDefault()
      const res= ysThree.getIntersectObject(el,event)
      if(res.objectList.length > 0) {
        const obj = res.objectList[0]
        if((obj.object.name === 'plane'|| obj.object.name ==='circle')&&!isMoving){ //如果是面或当前circle
          circle.position.copy(obj.point)
          circle.position.y = 0.2
          circle.visible = true
          $("body").css({
            cursor:'pointer'
          })

          if(currentHover)
            currentHover.visible = false
          currentHover = null
        }else{
          circle.visible = false
          if ( obj.object.name === 'box' ){
            if (currentHover) { currentHover.visible = false }
            currentHover = obj.object.getObjectByName('border')
            currentHover.visible = true
          }else{
            if(currentHover)
              currentHover.visible = false
            currentHover = null
          }
        }
      } else {
        circle.visible = false
        $("body").css({
          cursor:'grab'
        })
        if(currentHover)
          currentHover.visible = false
        currentHover = null
      }
    })
    let haveClick = false
    el.addEventListener('click',function (event) {
      event.preventDefault()
      const res= ysThree.getIntersectObject(el,event)
      if(res.objectList.length > 0) {
        const obj = res.objectList[0]
        if(obj.object.name ==='circle'){
          const x = circle.position.x
            ,z = circle.position.z,
            y = camera.position.y,
            v = camera.position.clone().sub(controls.target.clone()) //差
          haveClick = true
          ysThree.flyTo(TWEEN,controls,{
            position:[x ,y ,z],
            controls:[x-v.x ,y-v.y ,z-v.z],
            duration:500,
            done:function () {

            }
          })
        }else if(obj.object.name ==='box'){

          ys.dialog({
            maskLayer:true,//遮罩层, 高度是自适应也可以指定高度；
            width:"400px",
            tit:"提示",
            closeable:false,
            msg:"窗前明月光</br></br>疑似地上霜？",
            buttons:[
              {
                name:"确定",
                callback:function (e) {
                  console.log(e);
                  ys.messageBox({
                    tit:"操作",
                    msg:"你确定了",
                    icon:"smile",
                  })
                }
              }
            ]
          })
        }
      }else{

      }
    })


    //手机端 手机端监听点击使用 touchstart
    if(ysThree.isMobile()) {
      el.addEventListener('touchstart', function(event) {
        event.preventDefault()
        const res= ysThree.getIntersectObject(el,event)
        if(res.objectList.length > 0) {
          const obj = res.objectList[0]
          if(obj.object.name === 'plane'){
            circle.position.copy(obj.point)
            circle.position.y = 0.01
            const x = circle.position.x
              ,z = circle.position.z,
              y = camera.position.y,
              v = camera.position.clone().sub(controls.target.clone()) //差
            haveClick = true
            ysThree.flyTo(TWEEN,controls,{
              position:[x ,y ,z],
              controls:[x-v.x ,y-v.y ,z-v.z],
              duration:500,
              done:function () {

              }
            })
          }else if(obj.object.name ==='box'){

          }
        }else{

        }
      })
    }

    /*  ***********/
    function initControls() {
      const  controls = new OrbitControls(camera, renderer.domElement);
      // 如果使用animate方法时，将此函数删除
      //controls.addEventListener( 'change', render );
      // 使动画循环使用时阻尼或自转 意思是否有惯性
      controls.enableDamping = true;
      //动态阻尼系数 就是鼠标拖拽旋转灵敏度
      //controls.dampingFactor = 0.25;
      //是否可以缩放
      controls.enableZoom = false;
      //是否自动旋转
      // controls.autoRotate = true;
      controls.autoRotateSpeed = 0.3;
      //设置相机距离原点的最远距离
      controls.minDistance = 1;
      //设置相机距离原点的最远距离
      controls.maxDistance = 1000;
      //是否开启右键拖拽
      controls.enablePan = false
      return controls
    }
    const  controls = initControls()

    controls.target.set(0,20,0)
    camera.position.set(0.0001,20,0.0001) //差值使相机向前看。

    let count = 1
    const clock= new THREE.Clock()
    function initStats() {
      const stats = new Stats()
      stats.setMode(0); // 0: fps, 1: ms
      stats.domElement.style.position = 'absolute';
      stats.domElement.style.left = '0px';
      stats.domElement.style.top = '0px';
      document.body.appendChild(stats.domElement);
      return stats
    }
    // const stats = initStats()
    function animate() {


      requestAnimationFrame(animate)
      renderer.render(scene,camera)
      controls.update(clock.getDelta())

      TWEEN.update()

      if(haveClick && circleBorder){
        count = count + 0.05
        circleBorder.material.opacity =  circleBorder.material.opacity - 0.05
        if(count > 2){
          count = 1
          circleBorder.material.opacity =1
          haveClick = false
        }
        circleBorder.scale.set(count,count,count)
      }

      // if(stats) stats.update()
    }
    animate()

  })
</script>
</html>
